package router

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"go-ddd/infrastructure/app"
	"go-ddd/ui/dto"
	"net/http"
	"runtime"
)

type handler func(c *gin.Context) (dto.Data, error)

func wrapper(handler handler) func(c *gin.Context) {
	return func(c *gin.Context) {
		defer func() {
			if r := recover(); r != nil {
				// 未知panic错误
				DeliverPanicStack(r)
				toJSON(c, app.StatusPanicError, app.Message[app.StatusPanicError], nil)
			}
		}()

		code := app.StatusOK
		message := app.Message[app.StatusOK]
		data, err := handler(c)
		if err != nil {
			code = app.StatusError
			message = err.Error()
			// 自定义错误
			error, ok := err.(app.Error)
			if ok {
				code, message = error.Code, error.Message
				if message == "" {
					message = app.Message[code]
				}
			}
		}
		toJSON(c, code, message, data)
	}
}

func toJSON(c *gin.Context, code int, message string, data dto.Data) {
	c.JSON(http.StatusOK, dto.Response{Code: code, Message: message, Data: data})
}

func DeliverPanicStack(panic interface{}) {
	var buf [4096]byte
	n := runtime.Stack(buf[:], false)
	fmt.Printf("panic:\n%v\n %s\n", panic, string(buf[:n]))
	// 日志投递
}
